{cp866}
uses routine,Process,DispProc;
var
	d:TDispatcherProcess;
	T:longint;	
{так как в примере все процессы имеют различные илентификаторы}
{для сравнения двух процессов достаточно сравнить их id}
{данная функция сравнивает два процесс по их id}
function compareByID(const p1:pointer; const p2:pointer):boolean;
far;
var
	proc1:PProcess;
	proc2:PProcess;
begin
	proc1:=p1;
	proc2:=p2;
	compareByID:=(proc1^.get_id = proc2^.get_id);
end;
procedure test_delay_time;
far;
var
	s:string;
	p:PDispatcherProcess;
	curProcess:TProcess;
	count:longint;
begin
	count:=0;
	p:=get_current_dispatcher;
	p^.get_current_process(curProcess);
	while true do
		begin
			p^.lock;
			writeln('Этот процесс 20 раз выведет на экран свой id и будет задержан',
					'на ', T, ' вызовов таймера');
			readln;
			p^.unlock;
			while (count < 20) do
				begin
					writeln('pid: ', curProcess.get_id);
					inc(count);
				end;
			p^.delayTimeProcess(T);
			p:=get_current_dispatcher;
			p^.get_current_process(curProcess);
			count:=0;
			p^.lock;			
			writeln('Процесс с pid:', curProcess.get_id, ' был снова активизирован');
			readln;
			p^.unlock;
			while (count < 2000) do
				begin
					writeln('pid: ', curProcess.get_id);
					inc(count);
				end;
			p^.lock;
			writeln('процесс с id: ',curProcess.get_id,' будет уничтожен');
			readln;			
			p^.unlock;
			break;
		end;
	{текущий процесс уничтожается}
	p^.killCurrentProcess;
end;

procedure proc;
far;
var
	cur:TProcess;
	p:PDispatcherProcess;
	{количество готовых процессов}
begin
	p:=get_current_dispatcher;
	p^.get_current_process(cur);
	while true do
		begin
		end;

end;
procedure main_proc;
far;
var
	key:char;
	id:word;
	numberProcess:word;
	cur:TProcess;
	tempProcess:	TProcess;
	comand:string;
	{массив некритичных процессов}
	array_id:array[1..100] of word;
	i:word;
	curPID:word;
begin
	while true do
		begin
			{блокируем диспетчер}
			if (isEscape) then
			begin
			get_current_dispatcher^.lock;
				numberProcess:=get_current_dispatcher^.getNumberReadyProcess;
				get_current_dispatcher^.getArrayOfReadyPID(array_id);				
				get_current_dispatcher^.get_current_process(cur);
				curPID:=cur.get_id;
				{главным процессом является процесс с максимальным id}
				writeln('Всего доступно процессов для выполнения: ', numberProcess);
				writeln('Из них процесс с id: ', 
						curPID,
						' является управляющим');
				writeln('Процесс с id ',
						curPID - 1,
						' предназначен для тестирования ',#13,#10,
						'задержки процессов на время и уничтожения процессов.');
				numberProcess:=get_current_dispatcher^.getNumberDelayProcess;				
				writeln('На данный момент задержано процессов: ', numberProcess);
				writeln('Выберите один из следующих пунктов:');
				writeln('0) Продолжить выполнение');
				writeln('1) Задержать один из не критичных проектов');
				writeln('2) Возобновить один из задержанных процессов');
				writeln('3) Удалить один из некритичных процессов');
				writeln('4) Создать новый процесс и добавить его в',
							' диспетчер для выполнения');
				writeln('5) Вывести id всех выполняемых процессов');
				writeln('6) Вывести id всех задержанных процессов');
				writeln('7) Прекратить выполнение процессов');
				readln(comand);
				case (ord(comand[1]) - 48) of
					0:
						begin
							get_current_dispatcher^.unlock;
							asm
								int 8;
							end;
						end;
					1:
						begin
							{получаем массив id of all readyProcess}
							numberProcess:=get_current_dispatcher^.getNumberReadyProcess;
							get_current_dispatcher^.getArrayOfReadyPID(array_id);
							writeln('Cписок доступных некритичных процессов:');
							{главным процессом является процесс с максимальным id}
							for i:=1 to numberProcess do
								if (array_id[i] <> curPID) and (array_id[i] <> (curPID - 1)) then
									write('pid[',i,']: ', array_id[i], ', ');
							writeln;
							writeln('выберите id процесса, который нужно задержать');
							readln(id);
							tempProcess.set_id(id);
							get_current_dispatcher^.unlock;							
							get_current_dispatcher^.delayProcessByComparator(tempProcess, compareByID);
							asm
								int 8;
							end;
						end;
					2:
						begin
							{получаем массив id of all delayProcess}
							get_current_dispatcher^.getArrayOfDelayPID(array_id);
							writeln('Cписок доступных задержанных процессов:');
							numberProcess:=get_current_dispatcher^.getNumberDelayProcess;
							for i:=1 to numberProcess do
									write('pid[',i,']: ', array_id[i], ', ');
							writeln;
							writeln('выберите id процесса, который нужно воостановить');
							readln(id);
							tempProcess.set_id(id);
							get_current_dispatcher^.resumeProcessByComparator(tempProcess, compareByID);							
							get_current_dispatcher^.unlock;
							asm
								int 8;
							end;
						end;
					3:
						begin
							{получаем массив id of all readyProcess}
							numberProcess:=get_current_dispatcher^.getNumberReadyProcess;
							get_current_dispatcher^.getArrayOfReadyPID(array_id);
							writeln('Cписок доступных некритичных процессов:');
							for i:=1 to numberProcess do
								if (array_id[i] <> curPID) and (array_id[i] <> (curPID - 1)) then
									write('pid[',i,']: ', array_id[i], ', ');
							writeln;
							writeln('выберите id процесса, который нужно уничтожить');
							readln(id);
							tempProcess.set_id(id);
							get_current_dispatcher^.unlock;							
							get_current_dispatcher^.killProcessByComparator(tempProcess, compareByID);							
							asm
								int 8;
							end;
						end;
					4:
						begin
							get_current_dispatcher^.add_new_process(proc);
							get_current_dispatcher^.unlock;
							asm
								int 8;
							end;
						end;
					5:
						begin
							numberProcess:=get_current_dispatcher^.getNumberReadyProcess;
							for i:=1 to numberProcess do
									write('pid[',i,']: ', array_id[i], ', ');
							writeln;
						end;
					6:
						begin
							numberProcess:=get_current_dispatcher^.getNumberDelayProcess;
							for i:=1 to numberProcess do
									write('pid[',i,']: ', array_id[i], ', ');
							writeln;

						end;

					7:
						begin
							get_current_dispatcher^.stop;
						end;
					end;
			end;
		end;
end;
var
	a:array [1..40] of body_Process;
	i:integer;
	main:descptr;	
	numberProcess:integer;
	oldMemory, newMemory:longint;
begin
        oldMemory:=MemAvail;
	T:=400;
	new(main);
	writeln('Введите количество процессов > 2');
	readln(numberProcess);
	for i:= 1 to numberProcess-2 do
		a[i]:=proc;
	a[numberProcess-1]:=test_delay_time;
	a[numberPRocess]:=main_proc;
	d.init(numberProcess,a,main);
	set_current_dispatcher(@d);	
	d.start;
	writeln('oldMemory: ', oldMemory);
	writeln('curMemory: ', MemAvail);
	dispose(main);
	d.done;
	newMemory:=MemAvail;
	writeln('newMemory',newMemory);
	
end.